package com.zt.bigdata.elasticsearch.controller;

import com.zt.bigdata.elasticsearch.dao.AccountRepository;
import com.zt.bigdata.elasticsearch.entity.Account;
import com.zt.bigdata.elasticsearch.utils.transport.ESClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 *
 */
@Api(value = "/index", description = "索引操作")
@RestController
@RequestMapping("/index")
public class Controller {
    private static final Logger logger = LoggerFactory.getLogger(Controller.class);
    @Autowired
    AccountRepository accountRepository;
    @Autowired
    ESClient esClient;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @RequestMapping("/getById/{id}")
    public Account getByAccountNumber(@PathVariable("id") String id) {
        Account account = accountRepository.findAccountById(id);
        logger.info("account :{}", account);
        return account;
    }

    @RequestMapping("/getByFullName")
    public Account findBankByFirstNameAndLastName(@RequestParam String firstname, @RequestParam String lastname) {
        Account account = accountRepository.findAccountByFirstname(firstname);
        logger.info("account :{}", account);
        return account;
    }


    @PutMapping()
    public boolean save(@RequestBody Account account) {
        Account account1 = accountRepository.save(account);
        return null == account1 ? false : true;
    }

    @PostMapping
    public Account update(@RequestBody Account account) {

        Account account1 = accountRepository.findAccountByFirstnameAndLastname(account.getFirstname(), account.getLastname());
        if (null == account1) {
            account.setId(UUID.randomUUID().toString());
            return accountRepository.save(account);
        } else {
            account.setId(account1.getId());
            account.setVersion(account1.getVersion() + 1);
            return accountRepository.save(account);
        }
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable String id) {
        accountRepository.deleteById(id);
    }


    //指标分析
    @ApiOperation(value = "/findByState/{state}", notes = "获取所有")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页", dataType = "int", paramType = "query", required = false, defaultValue = "0"),
            @ApiImplicitParam(name = "size", value = "行数", dataType = "int", paramType = "query", defaultValue = "10"),
            @ApiImplicitParam(name = "state", value = "州", dataType = "string", paramType = "path")
    })
    @GetMapping("/findByState/{state}")
    public Page<Account> findByState(@PathVariable String state,
                                     @RequestParam(value = "page", defaultValue = "0") Integer page,
                                     @RequestParam(value = "size", defaultValue = "10") Integer size) {
        Pageable pageable = PageRequest.of(page, size);
        return accountRepository.findByState(state, pageable);
    }

    @GetMapping("/findByGender/{gender}")
    public Page<Account> findByGender(@PathVariable String gender,
                                      @RequestParam(value = "page", defaultValue = "0") Integer page,
                                      @RequestParam(value = "size", defaultValue = "10") Integer size) {
        Pageable pageable = PageRequest.of(page, size);
        return accountRepository.findByGender(gender, pageable);
    }

    @GetMapping("/findBankByAgeBetween/")
    public Page<Account> findByGender(@RequestParam("left") Integer left,
                                      @RequestParam("right") Integer right,
                                      @RequestParam(value = "page", defaultValue = "0") Integer page,
                                      @RequestParam(value = "size", defaultValue = "10") Integer size) {
        Pageable pageable = PageRequest.of(page, size);
        return accountRepository.findBankByAgeBetween(left, right, pageable);
    }

    @GetMapping("/findBankByAgeBetweenAndGender/{gender}")
    public Page<Account> findBankByAgeBetweenAndGender(@PathVariable String gender,
                                                       @RequestParam("left") Integer left,
                                                       @RequestParam("right") Integer right,
                                                       @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                       @RequestParam(value = "size", defaultValue = "10") Integer size) {
        Pageable pageable = PageRequest.of(page, size);
        return accountRepository.findBankByAgeBetweenAndGender(left, right, gender, pageable);
    }

    @GetMapping("/findBankByFuzzyAddress/{address}")
    public Page<Account> findBankByFuzzyAddress(@PathVariable String address,
                                                @RequestParam(value = "page", defaultValue = "0") Integer page,
                                                @RequestParam(value = "size", defaultValue = "10") Integer size) {
        Pageable pageable = PageRequest.of(page, size);
        SearchQuery searchQuery = getBankByFuzzyAddress(address, pageable);

        return accountRepository.search(searchQuery);
    }

    private SearchQuery getBankByFuzzyAddress(String address, Pageable pageable) {

        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("address", address);

        // 设置分页
        return new NativeSearchQueryBuilder()
                .withPageable(pageable)
                .withQuery(queryBuilder)
                .build();

    }

    @GetMapping("/fuzzyAddress/{address}")
    public Page<Account> matchAll(@PathVariable("address") String address) {
        Pageable pageable = PageRequest.of(0, 10);

        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("address", address);

        // 设置分页
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withPageable(pageable)
                .withQuery(queryBuilder)
                .build();

        return elasticsearchTemplate.queryForPage(searchQuery, Account.class);
    }


    @GetMapping("/matchAll")
    public List<Map<String, Object>> matchAll() {
        return esClient.matchAll();
    }


    @GetMapping("/fuhaobang/{size}")
    public Map<String, List<Map<String, Object>>> fuhaobang(@PathVariable("size") Integer size) {
        return esClient.fuhaobang(size);
    }
}
